package kmeans;

import org.apache.hadoop.io.Writable;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;

public class Instance implements Writable {
    ArrayList<Double> value;//各维度的坐标

    public Instance() {
        value = new ArrayList<Double>();
    }

    public Instance(String line) {
        String[] StringValue = line.split(",");
        value = new ArrayList<Double>();
        for (String dimension : StringValue) {
            value.add(Double.parseDouble(dimension));
        }
    }

    public Instance(Instance instance) {
        value = new ArrayList<Double>(instance.value);
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof Instance) {
            Instance instance = (Instance) obj;
            if (value.size() == instance.value.size()) {
                for (int i = 0; i < value.size(); i++) {
                    if (!value.get(i).equals(instance.value.get(i))) {
                        return false;
                    }
                }
                return true;
            }
        }
        return false;
    }

    public double ComputeDist(Instance instance) {
        if (value.size() != instance.value.size()) {
            try {
                throw new Exception("cannot add: dimension not compatible " +
                        value.size() + "," + instance.value.size());
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }
        double result = 0;
        for (int i = 0; i < value.size(); i++) {
            result += Math.pow(value.get(i) - instance.value.get(i), 2);
        }
        return result;
    }

    public Instance add(Instance instance) {
        if (value.size() == 0) return new Instance(instance);
        if (value.size() != instance.value.size()) {
            try {
                throw new Exception("cannot add: dimension not compatible " +
                        value.size() + "," + instance.value.size());
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
        Instance result = new Instance();
        for (int i = 0; i < value.size(); i++) {
            result.value.add(value.get(i) + instance.value.get(i));
        }
        return result;
    }

    public Instance multiply(Long num) {
        Instance result = new Instance();
        for (int i = 0; i < value.size(); i++) {
            result.value.add(value.get(i) * num);
        }
        return result;
    }

    public Instance divide(Long num) {
        Instance result = new Instance();
        for (int i = 0; i < value.size(); i++) {
            result.value.add(value.get(i) / num);
        }
        return result;
    }

    @Override
    public String toString() {
        StringBuilder s = new StringBuilder();
        for (Double aDouble : value) {
            s.append(aDouble).append(",");
        }
        return s.toString();
    }

    @Override
    public void write(DataOutput dataOutput) throws IOException {
        dataOutput.writeInt(value.size());
        for (Double dimension : value) {
            dataOutput.writeDouble(dimension);
        }
    }

    @Override
    public void readFields(DataInput dataInput) throws IOException {
        int size = dataInput.readInt();
        if (size > 0) {
            value = new ArrayList<Double>();
            for (int i = 0; i < size; i++) {
                value.add(dataInput.readDouble());
            }
        }
    }
}
